#include <stdlib.h>
#include "Behavior/setAlejar.h"
#include "Kinematic.h"
#include "State.h"
#include "CApp.h"
#include "Graph.h"
#include <SDL/SDL.h>
#include <SDL/SDL_gfxPrimitives.h>

Steering* State::getSteering(){
  return b->getSteering();
}

void State::Atacar(Uint32 o,Kinematic *myK){
  if (SDL_GetTicks() - o> 1550){
    theApp.atacar(myK);
    old_time = SDL_GetTicks();
  }
}

State* State::processYells(Kinematic *player,setBehavior *b){
  return NULL;
}

State* State::processPlayer(){
  return NULL;
}

//=================={{{{{{{====================//

WaitingP::WaitingP(setBehavior *_b){
  b = _b;
}

State* WaitingP::procces(int life, Kinematic *myK,Kinematic *player,bool enemyCerca, vector<setBehavior*>bs,int max_life){
  int a = random();
  float aux[3];
  restarVectores(myK->position,player->position,aux);
  if (enemyCerca){
    Character *c = theApp.getEnemyToAttack(myK);
    if (!c)
      return NULL;
    bs[PATTACK]->SetTarget(c);
    theApp.Yells(myK);
    return new AttackP(bs[PATTACK]);
  }
  else if (length(aux) <= 100 && !(a%10)){
    return new SeekP(bs[PSEEK]);
  }
  else if (float(life)/max_life <= 0.5){
//else if (true){
    Node *node =graph_heal.findNearestNode(myK->position);
    float aux[3] = {(*node)[0],(*node)[1],(*node)[2]};
    bs[PHEAL]->SetTarget(new Character(new Kinematic(aux)));
    return new Heal(bs[PHEAL]);
  }
  return NULL;
}

State* WaitingP::processYells(Kinematic *player,setBehavior *b){
  return new Go(player,b);
}

State* WaitingP::processPlayer(){
  return NULL;
}
//==================}}}}}}}====================//

//=================={{{{{{{====================//
Run::Run(setBehavior *_b){
  b = _b;
  old_time = SDL_GetTicks();
}
State* Run:: procces(int life, Kinematic *myK, Kinematic *player,bool enemyCerca, vector<setBehavior*>bs,int max_life){
  if (SDL_GetTicks() - old_time > 3000){
    old_time = SDL_GetTicks();
    Node *node =graph_heal.findNearestNode(myK->position);
    float aux[3] = {(*node)[0],(*node)[1],(*node)[2]};
    bs[PHEAL]->SetTarget(new Character(new Kinematic(aux)));
    return new Heal(bs[PHEAL]);
  }
  Character* c = theApp.enemyMasCercano(myK);
  if (c != NULL){
   ((setAlejar*)b)->SetTarget(c);
    return NULL;
  }
  return new WaitingP(bs[PWAITINGP]);
}

State* Run::processYells(Kinematic *player,setBehavior *b){
  return NULL;
}

State* Run::processPlayer(){
  return NULL;
}
//==================}}}}}}}====================//

//=================={{{{{{{====================//

SeekP::SeekP(setBehavior *_b){
  b = _b;
}

State* SeekP:: procces(int life, Kinematic *myK, Kinematic *player,bool enemyCerca, vector<setBehavior*>bs,int max_life){
  float aux[3];
  restarVectores(myK->position,player->position,aux);
  if (enemyCerca){
    return new AttackP(bs[PATTACK]);
  }else if (length(aux) >= 150){
    return new WaitingP(bs[PWAITINGP]);
  }
  return NULL;
}

State* SeekP::processYells(Kinematic *player,setBehavior *b){
  return NULL;
}

State* SeekP::processPlayer(){
  return NULL;
}
//==================}}}}}}}====================//


//=================={{{{{{{====================//

AttackP::AttackP(setBehavior *_b){
  b = _b;
  old_time = SDL_GetTicks();
}

State* AttackP::procces(int life, Kinematic *myK,Kinematic *player,bool enemyCerca, vector<setBehavior*>bs,int max_life){
  if (bs[PATTACK]->GetTarget()->isDead())
    return new WaitingP(bs[PWAITINGP]);
  if (float(life)/max_life < 0.3){
    if (random()%2){
      Node *node =graph_heal.findNearestNode(myK->position);
      float aux[3] = {(*node)[0],(*node)[1],(*node)[2]};
      bs[PHEAL]->SetTarget(new Character(new Kinematic(aux)));
      return new Heal(bs[PHEAL]);
    }else{
      return new Run(bs[PRUN]);
    }
  }
  else if (float(life)/max_life < 0.5 && random()%11){
    if (!random()%4){
      Node *node =graph_heal.findNearestNode(myK->position);
      float aux[3] = {(*node)[0],(*node)[1],(*node)[2]};
      bs[PHEAL]->SetTarget(new Character(new Kinematic(aux)));
      return new Heal(bs[PHEAL]);
    }else{
      return new Run(bs[PRUN]);
    }
  }
  if (SDL_GetTicks()- old_time > 1550){
    vector<Character*> en = theApp.getEnemyNear(myK);
    for (int i =0, n = en.size(); i < n;i++){
      en[i]->atacado();
    }
    old_time = SDL_GetTicks();
  }
  return NULL;
}

State* AttackP::processYells(Kinematic *player,setBehavior *b){
  return NULL;
}

State* AttackP::processPlayer(){
  return NULL;
}

//==================}}}}}}}====================//

//=================={{{{{{{====================//
Go::Go(Kinematic *point, setBehavior *_b){
  b = _b;
  Character *c = new Character(new Kinematic(*point));
  b->SetTarget(c);
  old_time = SDL_GetTicks();

}

State* Go::procces(int life, Kinematic *myK,Kinematic *player,bool enemyCerca, vector<setBehavior*>bs,int max_life){
  if (enemyCerca){
    Character * c = theApp.getEnemyToAttack(myK);
    if (!c)
      return NULL;
    bs[PATTACK]->SetTarget(c);
    theApp.Yells(myK);
    return new AttackP(bs[PATTACK]);
  }else if (SDL_GetTicks() - old_time > 5000){
    return new WaitingP(bs[PWAITINGP]);
  }
  return NULL;
}

State* Go::processYells(Kinematic *player,setBehavior *b){
  return NULL;
}

State* Go::processPlayer(){
  return NULL;
}
//==================}}}}}}}====================//

//=================={{{{{{{====================//

Heal::Heal(setBehavior *_b){
//cout << "Entro a curarse" << endl;
  b = _b;
}

State* Heal::procces(int life, Kinematic *myK,Kinematic *player,bool enemyCerca, vector<setBehavior*>bs,int max_life){
  if (life == max_life){
    return new WaitingP(bs[PWAITINGP]);
  }else if (enemyCerca && float(life)/max_life < 0.23 && !random()%9)
    return new Run(bs[PRUN]);
  return NULL;
}

State* Heal::processYells(Kinematic *player,setBehavior *b){
  return NULL;
}

State* Heal::processPlayer(){
  return NULL;
}

//==================}}}}}}}====================//

//=================={{{{{{{====================//

SeekPNow::SeekPNow(setBehavior *_b){
  b = _b;
}

State* SeekPNow::procces(int life, Kinematic *myK,Kinematic *player,bool enemyCerca, vector<setBehavior*>bs,int max_life){
  for (int cont=0,n = naves.size();cont < n ; cont++){
    float aux[3];
    Kinematic *b = naves[cont]->getKinematic();
    restarVectores(myK->position,b->position,aux);
    if (termino && length(aux) < 50 && naves[cont]->follow()){
      bs[5]->SetTarget(naves[cont]);
      return new FNave(bs[5]);
    }
    delete(b);
    
  }
  return NULL;
}

State* SeekPNow::processYells(Kinematic *player,setBehavior *b){
  return NULL;
}

State* SeekPNow::processPlayer(){
  return NULL;
}
//==================}}}}}}}====================//
//=================={{{{{{{====================//

WaitingPE::WaitingPE(setBehavior *_b){
  b = _b;
  old_time = SDL_GetTicks();
}

State* WaitingPE::procces(int life, Kinematic *myK,Kinematic *player,bool enemyCerca, vector<setBehavior*>bs,int max_life){
  if (enemyCerca){
    return new AttackPE(bs[PATTACKE]);
  }else if (life < 50){
    return new RunPE(bs[PRUNE]);
  }
  return NULL;
}

State* WaitingPE::processYells(Kinematic *player,setBehavior *b){
  return new GoPE(player,b);
}

State* WaitingPE::processPlayer(){
  return NULL;
}

//==================}}}}}}}====================//

AttackPE::AttackPE(setBehavior *_b){
  b = _b;
  old_time = SDL_GetTicks();
}

State* AttackPE::procces(int life, Kinematic *myK,Kinematic *player,bool enemyCerca, vector<setBehavior*>bs,int max_life){
  State::Atacar(old_time,myK);
  if (bs[PATTACKE]->GetTarget()->isDead())
    return new WaitingPE(bs[PWAITINGPE]);
  if (life < 50){
    return new RunPE(bs[PRUNE]);
  }
  return NULL;
}

State* AttackPE::processYells(Kinematic *player,setBehavior *b){
  return NULL;
}

State* AttackPE::processPlayer(){
  return NULL;
}


GoPE::GoPE(Kinematic *point, setBehavior *_b){
  b = _b;
  Character *c = new Character(new Kinematic(*point));
  b->SetTarget(c);
  old_time = SDL_GetTicks();

}

State* GoPE::procces(int life, Kinematic *myK,Kinematic *player,bool enemyCerca, vector<setBehavior*>bs,int max_life){
  State::Atacar(old_time,myK);
  if (enemyCerca){
    Character * c = theApp.enemyCerca(myK);
    if (!c){
      return NULL;
    }
    bs[PATTACKE]->SetTarget(c);
    return new AttackPE(bs[PATTACKE]);
  }else if (SDL_GetTicks() - old_time > 5000){
    old_time = SDL_GetTicks();
    return new WaitingP(bs[PWAITINGPE]);
  }
  return NULL;
}

State* GoPE::processYells(Kinematic *player,setBehavior *b){
  return NULL;
}

State* GoPE::processPlayer(){
  return NULL;
}

RunPE::RunPE(setBehavior *_b){
  b = _b;
  old_time = SDL_GetTicks();
  _flash_pikmen->k->max_velocity = 0.22;
}

State* RunPE:: procces(int life, Kinematic *myK, Kinematic *player,bool enemyCerca, vector<setBehavior*>bs,int max_life){
  State::Atacar(old_time,myK);
  Character* c = theApp.enemyCerca(myK);
  if (c != NULL){
   ((setAlejar*)b)->SetTarget(c);
    return NULL;
  }
  _flash_pikmen->k->max_velocity = 0.06;
  return new WaitingPE(bs[PWAITINGPE]);
}

State* RunPE::processYells(Kinematic *player,setBehavior *b){
  return NULL;
  _flash_pikmen->k->max_velocity = 0.06;
}

State* RunPE::processPlayer(){
  return NULL;
}

FNave::FNave(setBehavior* _b){
  b = _b;
}

State* FNave::procces(int life, Kinematic *myK,Kinematic *player,bool enemyCerca, vector<setBehavior*>bs,int max_life){
  return NULL;
}

State* FNave::processPlayer(setBehavior* _b){
  return new WaitingP(_b);
}

State* FNave::processPlayer(){
  return NULL;
}

State* FNave::processYells(Kinematic *player,setBehavior *b){
  return NULL;
}
